package club.xyes.zkh.ecommerce.web.api.controller;

import club.xyes.zkh.ecommerce.commons.entity.Shop;
import club.xyes.zkh.ecommerce.commons.entity.ShopMembership;
import club.xyes.zkh.ecommerce.commons.entity.ShopMembershipLevel;
import club.xyes.zkh.ecommerce.commons.properties.WebsiteConfigurationProperties;
import club.xyes.zkh.ecommerce.commons.util.EntityImagePathUtils;
import club.xyes.zkh.ecommerce.commons.util.TextUtil;
import club.xyes.zkh.ecommerce.commons.vo.GeneralCollectionResult;
import club.xyes.zkh.ecommerce.commons.vo.GeneralResult;
import club.xyes.zkh.ecommerce.commons.vo.ShopMembershipLevelText;
import club.xyes.zkh.ecommerce.service.ShopMembershipLevelService;
import club.xyes.zkh.ecommerce.service.ShopMembershipService;
import club.xyes.zkh.ecommerce.service.ShopService;
import club.xyes.zkh.ecommerce.web.controller.BaseController;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Create by 郭文梁 2019/4/18 0018 14:47
 * ShopMembershipController
 * 商铺会员定义相关数据访问控制器
 *
 * @author 郭文梁
 * @data 2019/4/18 0018
 */
@RestController
@RequestMapping("/api/shop-membership")
public class ShopMembershipController extends BaseController<ShopMembership> {
    /**
     * 默认会员卡图片
     */
    private static final String DEFAULT_MEMBERSHIP_IMAGE = "default.png";
    private final ShopMembershipService service;
    private final ShopService shopService;
    private final WebsiteConfigurationProperties websiteConfigurationProperties;
    private final ShopMembershipLevelService shopMembershipLevelService;

    @Autowired
    public ShopMembershipController(ShopMembershipService service,
                                    ShopService shopService,
                                    WebsiteConfigurationProperties websiteConfigurationProperties,
                                    ShopMembershipLevelService shopMembershipLevelService) {
        super(service);
        this.service = service;
        this.shopService = shopService;
        this.websiteConfigurationProperties = websiteConfigurationProperties;
        this.shopMembershipLevelService = shopMembershipLevelService;
    }

    /**
     * 获取当前用户所拥有商铺的会员信息
     *
     * @return GR
     */
    @GetMapping("/mine")
    @ApiOperation("获取当前用户所拥有商铺的会员信息")
    public GeneralResult<?> mine() {
        Shop shop = currentShop();
        List<ShopMembership> res = service.findByShop(shop);
        if (res.size() <= 0) {
            ShopMembership membership = service.createDefault(shop);
            res.add(membership);
        }
        res = EntityImagePathUtils.prettyShopMembershipImagePath(res, websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getShopMembershipImagePath());
        return GeneralCollectionResult.ok(res);
    }

    /**
     * 更新会员信息
     *
     * @param id    数据ID
     * @param param (name, expireTime, enabled)
     * @return GR
     */
    @PostMapping("/{id}")
    @ApiOperation("更新会员信息")
    public GeneralResult<ShopMembership> update(@PathVariable("id") Integer id,
                                                @RequestBody ShopMembership param) {

        if (!checkParam(param)) {
            return GeneralResult.badRequest("缺少参数");
        }
        ShopMembership membership = service.getRequired(id);
        Shop shop = currentShop();
        if (!Objects.equals(shop.getId(), membership.getShopId())) {
            return GeneralResult.permissionDenied("您无权操作该数据");
        }
        membership.setName(param.getName());
        membership.setExpireTime(param.getExpireTime());
        membership.setEnabled(param.getEnabled());
        membership.setDescription(param.getDescription());
        ShopMembership res = service.updateById(membership);
        EntityImagePathUtils.prettyShopMembershipImagePath(res, websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getShopMembershipImagePath());
        return GeneralResult.ok(res);
    }

    /**
     * 检查参数
     *
     * @param param （name, expireTime,enabled）
     * @return GR
     */
    private boolean checkParam(ShopMembership param) {
        return !(
                param == null
                        || TextUtil.isTrimedEmpty(param.getName())
                        || param.getExpireTime() == null
                        || param.getEnabled() == null
        );
    }

    /**
     * 获取当前用户所拥有的商铺 若不存在 则抛出异常
     *
     * @return 商铺
     */
    @NotNull
    private Shop currentShop() {
        return currentShop(shopService);
    }

    /**
     * 创建会员卡
     *
     * @param param 参数(name, expireTime, enabled, description)
     * @return GR
     */
    @PostMapping("/")
    @ApiOperation("创建会员卡")
    public GeneralResult<ShopMembership> create(@RequestBody ShopMembership param) {
        if (!checkParam(param)) {
            return GeneralResult.badRequest("缺少参数");
        }
        Shop shop = currentShop();
        if (service.existsByShop(shop)) {
            return GeneralResult.badRequest("暂时只支持创建一张会员卡");
        }
        ShopMembership membership = new ShopMembership();
        membership.setShopId(shop.getId());
        membership.setShop(shop);
        membership.setName(param.getName());
        membership.setExpireTime(param.getExpireTime());
        membership.setEnabled(param.getEnabled());
        membership.setDescription(param.getDescription());
        membership.setImage(DEFAULT_MEMBERSHIP_IMAGE);
        ShopMembership res = service.save(membership);
        EntityImagePathUtils.prettyShopMembershipImagePath(res, websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getShopMembershipImagePath());
        return GeneralResult.ok(res);
    }

    /**
     * 设置会员卡图片
     *
     * @param imageFile 图片
     * @return GR
     * @throws IOException IO异常
     */
    @ApiOperation("设置会员卡图片")
    @PostMapping("/{id}/set-image")
    public GeneralResult<ShopMembership> setImage(@PathVariable("id") Integer id,
                                                  MultipartFile imageFile) throws IOException {
        if (imageFile == null || imageFile.isEmpty()) {
            return GeneralResult.badRequest("没有上传图片");
        }
        @NotNull Shop shop = currentShop();
        ShopMembership shopMembership = service.getRequired(id);
        if (!Objects.equals(shopMembership.getShopId(), shop.getId())) {
            return GeneralResult.permissionDenied("您无权操作该数据");
        }
        ShopMembership res = service.setImage(shopMembership, imageFile);
        EntityImagePathUtils.prettyShopMembershipImagePath(res, websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getShopMembershipImagePath());
        return GeneralResult.ok(res);
    }

    /**
     * 会员卡预览
     *
     * @param id 会员卡ID
     * @return GR
     */
    @ApiOperation("会员卡预览")
    @GetMapping("/{id}/overview")
    public GeneralResult<Map<String, Object>> overview(@PathVariable("id") Integer id) {
        ShopMembership membership = service.getRequiredByIdFetchAll(id);
        List<ShopMembershipLevel> levels = shopMembershipLevelService.findByMembershipId(id);
        String serverPrefix = websiteConfigurationProperties.getStaticServerPrefix();
        String shopLogoPath = websiteConfigurationProperties.getShopLogoPath();
        String imagePath = websiteConfigurationProperties.getShopMembershipImagePath();
        EntityImagePathUtils.prettyShopMembershipImagePath(membership, serverPrefix, imagePath);
        EntityImagePathUtils.prettyLogoPath(membership.getShop(), serverPrefix, shopLogoPath);
        Map<String, Object> res = new HashMap<>(3);
        res.put("membership", membership);
        res.put("levels", levels);
        res.put("levelText", levels.stream().map(ShopMembershipLevelText::of).collect(Collectors.toList()));
        return GeneralResult.ok(res);
    }
}
